package com.atguigu.dga.assess.assessor.quality;

import com.atguigu.dga.assess.assessor.AssessorTemplate;
import com.atguigu.dga.assess.bean.AssessParam;
import com.atguigu.dga.assess.bean.GovernanceAssessDetail;
import com.atguigu.dga.assess.bean.TDsTaskInstance;
import com.atguigu.dga.assess.service.TDsTaskInstanceService;
import com.atguigu.dga.util.CacheUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.util.List;
import java.util.stream.Collectors;

/**
 * Created by Smexy on 2023/11/2

 前一天(数据)的产出时效，超过前{days}天产出时效平均值n%。则给0分，其余10分
    days：最多取days天
 */
@Component("TABLE_PRODUCE_EFFICIENCY")
public class CheckTableProduceEfficiency extends AssessorTemplate
{
    @Autowired
    private TDsTaskInstanceService taskInstanceService;
    /*
        1.计算当天当前表Task运行的时长
            使用 timestampdiff(second,start_time,end_time ) 计算task运行的秒数。
                2023-05-26
        2.计算前n天当前表Task运行的平均时长
                3
                2023-05-25
                2023-05-24
                2023-05-23
                   使用 date_sub('2023-05-26',interval 3 day ) 计算要查询的起始时间
        3.比较
     */
    @Override
    protected void assess(AssessParam param, GovernanceAssessDetail detail) throws Exception {

        //取出参数
        Integer days = getIntegerValueFromConfig(param, "days");
        Integer n = getIntegerValueFromConfig(param, "n");
        //查询ds Task_instance运行的 endtime - starttime 计算出时长
        String threeDaysBefore = LocalDate.parse(param.getAssessDate()).minusDays(days).toString();
        //只返回  计算日期(封装到Bean的name上)和任务的执行时间(封装在id上)
        QueryWrapper<TDsTaskInstance> queryWrapper = new QueryWrapper<TDsTaskInstance>()
            // ge(列名,值)
            .ge("date(start_time)", threeDaysBefore)
            .eq("name", CacheUtil.getKey(param.getMetaInfo()))  //找当前表的任务
            .select("date(start_time) name", "timestampdiff(second,start_time,end_time ) id");

        List<TDsTaskInstance> result = taskInstanceService.list(queryWrapper);

        if (result.size() <= 1){
            //只在今天调度过，没有过去n天的调度记录
            return ;
        }
        //计算今天任务的执行时间
        Integer runTimeToday = result.stream()
                                .filter(t -> param.getAssessDate().equals(t.getName()))
                                .map(t -> t.getId())
                                .collect(Collectors.toList())
                                .get(0);

        //求过去n天的平均时间
        double avgRunTime = result.stream()
                                .filter(t -> !param.getAssessDate().equals(t.getName()))
                                .mapToLong(t -> t.getId())
                                .average()
                                .getAsDouble();

        //比较
        BigDecimal limit = BigDecimal.valueOf(avgRunTime).multiply(BigDecimal.valueOf(100 + n)).movePointLeft(2);

        //超过平均时间的n%
        if (BigDecimal.valueOf(runTimeToday).compareTo(limit) == 1){
            String template = "当前任务运行时效低,%s的运行时间是:%d秒,超过了过去%d天的平均时间%f秒 的 %d%%";
            String comment = String.format(template, param.getAssessDate(), runTimeToday, days, avgRunTime, n);
            assessScore(BigDecimal.ZERO,"运行时效有问题",comment,detail,false,null);
        }
    }
}
